#pragma once

#include <iostream>
#include <string>
#include "util.hpp"

namespace ns_log
{
    using namespace ns_util;

    // 日志等级
    enum
    {
        INFO, // 
        DEBUG,  // 
        WARNING, // 警告
        ERROR, // 错误 
        FATAL // 致命错误
    };

    inline std::ostream &Log(const std::string &level, const std::string &file_name, int line)
    {
        // 参数level传入日志等级
        // 参数file_name传入日志信息所在文件名
        // 参数line传入log函数所在行，往往用于帮我们确定报错行的位置


        // 添加日志等级
        std::string message = "[";
        message += level;
        message += "]";

        // 添加报错文件名称
        message += "[";
        message += file_name;
        message += "]";

        // 添加报错行
        message += "[";
        message += std::to_string(line);
        message += "]";

        // 日志时间戳
        message += "[";
        message += TimeUtil::GetTimeStamp();
        message += "]";

        // cout 本质 内部是包含缓冲区的
        std::cout << message; //不要endl进行刷新

        return std::cout;
    }
    // LOG(INFo) << "message" << "\n";
    // 开放式日志
    #define LOG(level) Log(#level, __FILE__, __LINE__)
    // 这样定义之后，我们就只用传一个level参数即可，日志信息所在文件和日志信息所在行均有系统自动生成
    // #level在cpp文件预处理时会被转化成"level"
        // # 操作符的作用
        // 功能：在宏定义中，# 会将紧跟其后的参数转换为对应的字符串字面量（包含参数的所有字符，包括空格和特殊符号）。
        // 本质：预处理阶段，宏中的 #参数 会被替换为用双引号包裹的字符串，例如 #x 会变成 "x"。
}